<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>fvOptions 浅析 | Giskard&#39;s CFD Learning Tricks</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="本篇简单介绍 OpenFOAM 中的 fvOptions。按照官方的介绍，fvOptions 是一个可以在指定区域内添加源项或者其他约束（比如固定温度，或者多孔介质等）的框架。本篇对 fvOptions 框架的源码做一个浅析。">
<meta property="og:type" content="article">
<meta property="og:title" content="fvOptions 浅析">
<meta property="og:url" content="http://xiaopingqiu.github.io/2016/03/20/fvOptions1/index.html">
<meta property="og:site_name" content="Giskard's CFD Learning Tricks">
<meta property="og:description" content="本篇简单介绍 OpenFOAM 中的 fvOptions。按照官方的介绍，fvOptions 是一个可以在指定区域内添加源项或者其他约束（比如固定温度，或者多孔介质等）的框架。本篇对 fvOptions 框架的源码做一个浅析。">
<meta property="og:image" content="/image/fvOptions/fvOptions.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="fvOptions 浅析">
<meta name="twitter:description" content="本篇简单介绍 OpenFOAM 中的 fvOptions。按照官方的介绍，fvOptions 是一个可以在指定区域内添加源项或者其他约束（比如固定温度，或者多孔介质等）的框架。本篇对 fvOptions 框架的源码做一个浅析。">
  
  
    <link rel="icon" href="/favicon.png">
  
  <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  <link rel="stylesheet" href="/css/style.css" type="text/css">
  
<!-- Google Analytics -->
<script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');

##ga('create', '[object Object]', 'auto');
ga('create', 'UA-62501686-1', 'auto');
ga('send', 'pageview');

</script>
<!-- End Google Analytics -->


</head>
<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">Giskard&#39;s CFD Learning Tricks</a>
      </h1>
      
        <h2 id="subtitle-wrap">
          <a href="/" id="subtitle">CFD and Scientific Computing</a>
        </h2>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
          <a class="main-nav-link" href="/atom.xml">Rss</a>
        
          <a class="main-nav-link" href="/about">About</a>
        
      </nav>
      <nav id="sub-nav">
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" results="0" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="q" value="site:http://xiaopingqiu.github.io"></form>
      </div>
    </div>
  </div>
</header>

      <div class="outer">
        <section id="main"><article id="post-fvOptions1" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2016/03/20/fvOptions1/" class="article-date">
  <time datetime="2016-03-20T07:24:30.000Z" itemprop="datePublished">2016-03-20</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/OpenFOAM/">OpenFOAM</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      fvOptions 浅析
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>本篇简单介绍 OpenFOAM 中的 fvOptions。按照<a href="http://www.openfoam.org/version2.2.0/fvOptions.php" target="_blank" rel="external">官方的介绍</a>，fvOptions 是一个可以在指定区域内添加源项或者其他约束（比如固定温度，或者多孔介质等）的框架。本篇对 fvOptions 框架的源码做一个浅析。</p>
<a id="more"></a>
<p>先来了解一下 fvOptions 框架的结构，以及，在求解器中是怎么调用 fvOptions 的。为了避免问题复杂化，先从一个简单的求解器开始：<code>scalarTransportFoam</code>。OpenFOAM-2.3.1 中的 <code>scalarTransportFoam</code> 中已经引入了 <code>fvOptions</code> ，而更早的 OpenFOAM-2.1.1 中，则没有使用 <code>fvOptions</code> 。对比之下，很容易发现引入 <code>fvOptions</code> 其实就只涉及到两处代码修改：1. 增加了一个头文件 <code>createFvOptions.H</code>；2. 在 T 方程中增加了一项 <code>fvOptions(T)</code> 。 根据 OpenFOAM 的习惯，可以猜测这里增加的 <code>fvOptions(T)</code>，从C++的角度来看，多半是一个基类的对象 <code>fvOptions</code> 在调用类中重载过的 <code>()</code> 操作符。以上便是从这段简单的求解器代码中产生的对 <code>fvOptions</code> 的第一印象，下面来仔细看看 <code>fvOptions</code> 这个框架的结构。</p>
<h5 id="1-_createFvOptions-H">1. createFvOptions.H</h5><p>既然求解器里只增加了这一个头文件，那就先从这个看起。这个文件位于 <code>src/fvOptions/include</code>，内容很简单，就一句话：<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="rule"><span class="attribute">fv</span>:<span class="value">:IOoptionList <span class="function">fvOptions</span>(mesh)</span></span>;</span><br></pre></td></tr></table></figure></p>
<p>从这里就很清楚地可以看出， <code>scalarTransportFoam</code> 中 T 方程中增加的 <code>fvOptions</code> 是 <code>IOoptionList</code> 类的对象。</p>
<h5 id="2-_IOoptionList_类">2. IOoptionList 类</h5><p>接下来看 <code>IOoptionList</code> 类。IOoptionList 类由两个文件组成： fvIOoptionList.H 和 fvIOoptionList.C。这里的目的在于了解 fvOptions 这个框架的结构，所以重点看头文件以及构造函数的定义。</p>
<ul>
<li>fvIOoptionList.H <figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="preprocessor">#ifndef IOoptionList_H</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">define</span> IOoptionList_H</span></span><br><span class="line"></span><br><span class="line"><span class="preprocessor">#<span class="keyword">include</span> "fvOptionList.H"</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">include</span> "IOdictionary.H"</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">include</span> "autoPtr.H"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> Foam</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">namespace</span> fv</span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> IOoptionList</span><br><span class="line">:</span><br><span class="line">    <span class="keyword">public</span> IOdictionary,</span><br><span class="line">    <span class="keyword">public</span> optionList</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Private Member Functions</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Create IO object if dictionary is present</span></span><br><span class="line">        <span class="function">IOobject <span class="title">createIOobject</span><span class="params">(<span class="keyword">const</span> fvMesh&amp; mesh)</span> <span class="keyword">const</span></span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Disallow default bitwise copy construct</span></span><br><span class="line">        IOoptionList(<span class="keyword">const</span> IOoptionList&amp;);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Disallow default bitwise assignment</span></span><br><span class="line">        <span class="keyword">void</span> <span class="keyword">operator</span>=(<span class="keyword">const</span> IOoptionList&amp;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Constructors</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Construct from components with list of field names</span></span><br><span class="line">        IOoptionList(<span class="keyword">const</span> fvMesh&amp; mesh);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Destructor</span></span><br><span class="line">        <span class="keyword">virtual</span> ~IOoptionList()</span><br><span class="line">        &#123;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Member Functions</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Read dictionary</span></span><br><span class="line">        <span class="function"><span class="keyword">virtual</span> <span class="keyword">bool</span> <span class="title">read</span><span class="params">()</span></span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">&#125; <span class="comment">// End namespace fv</span></span><br><span class="line">&#125; <span class="comment">// End namespace Foam</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">endif</span></span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>从头文件可以看出， <code>IOoptionList</code> 类继承自 <code>IOdictionary</code> 和 <code>optionList</code> 类。根据对 OpenFOAM 的了解，<code>IOdictionary</code> 类是处理跟 IO 有关的，所以这里这个类很可能是用来处理 fvOptions 相关的字典文件的。真正涉及到具体的 fvOptions 源项的内容，应该是在 <code>optionList</code> 中有相关定义。</p>
<ul>
<li>构造函数<figure class="highlight less"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">Foam</span><span class="pseudo">::fv</span><span class="pseudo">::IOoptionList</span><span class="pseudo">::IOoptionList</span></span><br><span class="line">(</span><br><span class="line">    const fvMesh&amp; mesh</span><br><span class="line">)</span><br><span class="line">:</span><br><span class="line">    <span class="tag">IOdictionary</span>(<span class="function">createIOobject</span>(mesh)), <span class="comment">//构造函数里创建fvOptions字典文件</span></span><br><span class="line">    <span class="tag">optionList</span>(mesh, *this)</span><br><span class="line">&#123;&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>构造函数中调用 <code>createIOobject</code> 函数来对父类 <code>IOdictionary</code> 进行初始化，并将自己(<code>*this</code>) 作为参数传递给了父类 <code>optionList</code> 。</p>
<ul>
<li>createIOobject 函数<br>构造函数中调用了 <code>createIOobject</code> 函数，而且这里的调用显然至关重要，所以需要看一下这个函数<figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line">Foam::IOobject Foam::fv::IOoptionList::createIOobject</span><br><span class="line">(</span><br><span class="line">    const fvMesh&amp; mesh</span><br><span class="line">) const</span><br><span class="line">&#123;</span><br><span class="line">    IOobject <span class="built_in">io</span></span><br><span class="line">    (</span><br><span class="line">        <span class="string">"fvOptions"</span>,</span><br><span class="line">        mesh.time().constant(),</span><br><span class="line">        mesh,</span><br><span class="line">        IOobject::MUST_READ,</span><br><span class="line">        IOobject::NO_WRITE</span><br><span class="line">    );</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (<span class="built_in">io</span>.headerOk())</span><br><span class="line">    &#123;</span><br><span class="line">        Info&lt;&lt; <span class="string">"Creating finite volume options from "</span></span><br><span class="line">            &lt;&lt; <span class="built_in">io</span>.instance()/<span class="built_in">io</span>.name() &lt;&lt; nl</span><br><span class="line">            &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">        <span class="built_in">io</span>.readOpt() = IOobject::MUST_READ_IF_MODIFIED;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">io</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        // Check <span class="keyword">if</span> the fvOptions file is <span class="keyword">in</span> system</span><br><span class="line">        <span class="built_in">io</span>.instance() = mesh.time().system();</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (<span class="built_in">io</span>.headerOk())</span><br><span class="line">        &#123;</span><br><span class="line">            Info&lt;&lt; <span class="string">"Creating finite volume options from "</span></span><br><span class="line">                &lt;&lt; <span class="built_in">io</span>.instance()/<span class="built_in">io</span>.name() &lt;&lt; nl</span><br><span class="line">                &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">            <span class="built_in">io</span>.readOpt() = IOobject::MUST_READ_IF_MODIFIED;</span><br><span class="line">            <span class="keyword">return</span> <span class="built_in">io</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">        &#123;</span><br><span class="line">            Info&lt;&lt; <span class="string">"No finite volume options present"</span> &lt;&lt; nl &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">            <span class="built_in">io</span>.readOpt() = IOobject::NO_READ;</span><br><span class="line">            <span class="keyword">return</span> <span class="built_in">io</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>这个函数的意图就很明显了：创建了一个 <code>IOobject</code> 对象，并从 <code>system</code> 中读入文件 <code>fvOptions</code> 的内容来初始化该对象。并且，如果 <code>system</code> 目录下不存在 <code>fvOptions</code> 文件，那就尝试在 <code>constant</code> 下寻找。如果仍找不到，那就放弃读取。</p>
<h5 id="3-_optionList_类">3. optionList 类</h5><p>这个类由三个源文件定义： fvOptionList.H ， fvOptionList.C 和 fvOptionListTemplates.C。这里依然是重点关注头文件。</p>
<ul>
<li>fvOptionList.H<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"><span class="preprocessor">#ifndef optionList_H</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">define</span> optionList_H</span></span><br><span class="line"></span><br><span class="line"><span class="preprocessor">#<span class="keyword">include</span> "PtrList.H"</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">include</span> "GeometricField.H"</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">include</span> "fvPatchField.H"</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">include</span> "fvOption.H"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> Foam</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">namespace</span> fv</span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> optionList</span><br><span class="line">:</span><br><span class="line">    <span class="keyword">public</span> PtrList&lt;option&gt;</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">protected</span>:</span><br><span class="line"></span><br><span class="line">    ......</span><br><span class="line"></span><br><span class="line">        <span class="keyword">const</span> dictionary&amp; optionsDict(<span class="keyword">const</span> dictionary&amp; dict) <span class="keyword">const</span>;</span><br><span class="line"></span><br><span class="line">        <span class="function"><span class="keyword">bool</span> <span class="title">readOptions</span><span class="params">(<span class="keyword">const</span> dictionary&amp; dict)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Constructors</span></span><br><span class="line">        optionList(<span class="keyword">const</span> fvMesh&amp; mesh);</span><br><span class="line"></span><br><span class="line">        optionList(<span class="keyword">const</span> fvMesh&amp; mesh, <span class="keyword">const</span> dictionary&amp; dict);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">        <span class="function"><span class="keyword">void</span> <span class="title">reset</span><span class="params">(<span class="keyword">const</span> dictionary&amp; dict)</span></span>;</span><br><span class="line"></span><br><span class="line">	......</span><br><span class="line"></span><br><span class="line">            <span class="comment">//- Return source for equation</span></span><br><span class="line">            <span class="comment">// 重载的括号操作符，在求解器里，方程的构造过程中调用的就是这些括号操作符。</span></span><br><span class="line">            <span class="keyword">template</span>&lt;<span class="keyword">class</span> Type&gt;</span><br><span class="line">            tmp&lt;fvMatrix&lt;Type&gt; &gt; <span class="keyword">operator</span>()</span><br><span class="line">            (</span><br><span class="line">                <span class="keyword">const</span> volScalarField&amp; rho,</span><br><span class="line">                GeometricField&lt;Type, fvPatchField, volMesh&gt;&amp; fld</span><br><span class="line">            );</span><br><span class="line"></span><br><span class="line">	......</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">&#125; <span class="comment">// End namespace fv</span></span><br><span class="line">&#125; <span class="comment">// End namespace Foam</span></span><br><span class="line"></span><br><span class="line"><span class="preprocessor">#ifdef NoRepository</span></span><br><span class="line">    <span class="preprocessor">#<span class="keyword">include</span> "fvOptionListTemplates.C"</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"><span class="preprocessor">#<span class="keyword">endif</span></span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>这里注意两点，一是 <code>optionList</code> 类继承自 <code>PtrList&lt;option&gt;</code> ，另一个是，这里出现了重载的运算符 <code>()</code> 。继承自 <code>PtrList&lt;option&gt;</code> 意味着很可能 fvOptions 类是支持同时定义多个源项的。</p>
<ul>
<li>构造函数<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="rule"><span class="attribute">Foam</span>:<span class="value">:fv::optionList::<span class="function">optionList</span>(const fvMesh&amp; mesh, const dictionary&amp; dict)</span><br><span class="line">:</span><br><span class="line">    PtrList&lt;option&gt;(),</span><br><span class="line">    <span class="function">mesh_</span>(mesh),</span><br><span class="line">    <span class="function">checkTimeIndex_</span>(mesh_.<span class="function">time</span>().<span class="function">startTimeIndex</span>() + <span class="number">2</span>)</span><br><span class="line">&#123;</span><br><span class="line">    <span class="function">reset</span>(<span class="function">optionsDict</span>(dict))</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>构造函数里，调用了 <code>reSet</code> 和 <code>optionsDict</code> 函数。下面看一下这两个函数的作用：</p>
<ul>
<li>optionsDict 函数<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> Foam::dictionary&amp; Foam::fv::optionList::optionsDict</span><br><span class="line">(</span><br><span class="line">    <span class="keyword">const</span> dictionary&amp; dict</span><br><span class="line">) <span class="keyword">const</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (dict.found(<span class="string">"options"</span>))</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span> dict.subDict(<span class="string">"options"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span> dict;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>这个函数需要一个参数 <code>const dictionary&amp; dict</code>，这个参数，显然是从构造函数的 <code>const dictionary&amp; dict</code> ，再回顾一下上文中，<code>IOoptionList</code> 中将自己本身（*this）传递给父类 <code>optionsDict</code> ，而且， <code>IOoptionList</code> 同时也继承自 <code>IOdictionary</code> 类，并且将从文件 <code>fvOptions</code> 类中读取的内容来对其父类 <code>IOdictionary</code> 类。所以这里不难理解，参数 <code>const dictionary&amp; dict</code> 其实就是文件 <code>fvOptions</code> 的内容。这里需要从文件中 <code>fvOptions</code> 寻找关键字 <code>options</code> ，如果找到，那就返回 <code>options</code> 所指定的 <code>subDict</code> ，否则就直接返回 <code>fvOptions</code> 本身。</p>
<ul>
<li>reset 函数<br>再来看 reset 函数：<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">void</span> Foam::fv::optionList::reset(<span class="keyword">const</span> dictionary&amp; dict)</span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">// Count number of active fvOptions</span></span><br><span class="line">    label count = <span class="number">0</span>;</span><br><span class="line">    forAllConstIter(dictionary, dict, iter)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (iter().isDict())</span><br><span class="line">        &#123;</span><br><span class="line">            count++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">this</span>-&gt;setSize(count);</span><br><span class="line">    label i = <span class="number">0</span>;</span><br><span class="line">    forAllConstIter(dictionary, dict, iter)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (iter().isDict())</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">const</span> word&amp; name = iter().keyword();</span><br><span class="line">            <span class="keyword">const</span> dictionary&amp; sourceDict = iter().dict();</span><br><span class="line"></span><br><span class="line">            <span class="keyword">this</span>-&gt;<span class="built_in">set</span></span><br><span class="line">            (</span><br><span class="line">                i++,</span><br><span class="line">                option::New(name, sourceDict, mesh_)</span><br><span class="line">            );</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>注意在构造函数里，这个函数的参数是 <code>optionsDict</code> 类的返回值。这里，函数是在统计 <code>fvOptions</code> 中有效的 <code>options</code> 的个数，并根据每一个有效的 <code>options</code> ，调用 <code>option</code> 类的 <code>New</code> 函数（看到 New 函数，很自然就会想到 Run Time Selection 吧！）来构造对象指针，且将该指针存到 <code>PtrList</code> 类定义的 List 里。 这里更是直接能看出来，在文件 <code>fvOptions</code> 中，是可以同时定义多个源项的。 </p>
<h5 id="4-_option_类">4. option 类</h5><p>再继续看 <code>option</code> 类。<code>option</code> 类由四个源文件定义： <code>fvOption.H</code> ， <code>fvOption.C</code> ， <code>fvOptionI.H</code> 和 <code>fvOptionIO.C</code> 。</p>
<ul>
<li><p>fvOption.H</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="preprocessor">#ifndef fvOption_H</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">define</span> fvOption_H</span></span><br><span class="line"></span><br><span class="line"><span class="preprocessor">#<span class="keyword">include</span> "fvMatricesFwd.H"</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">include</span> "volFieldsFwd.H"</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">include</span> "cellSet.H"</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">include</span> "autoPtr.H"</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">include</span> "meshToMesh.H"</span></span><br><span class="line"></span><br><span class="line"><span class="preprocessor">#<span class="keyword">include</span> "runTimeSelectionTables.H"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> Foam</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">class</span> fvMesh；</span><br><span class="line"><span class="keyword">namespace</span> fv</span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> option</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Public data</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Enumeration for selection mode types</span></span><br><span class="line">        <span class="keyword">enum</span> selectionModeType</span><br><span class="line">        &#123;</span><br><span class="line">            smPoints,</span><br><span class="line">            smCellSet,</span><br><span class="line">            smCellZone,</span><br><span class="line">            smMapRegion,</span><br><span class="line">            smAll</span><br><span class="line">        &#125;;</span><br><span class="line"></span><br><span class="line">......</span><br></pre></td></tr></table></figure>
<p><code>option</code> 类终于不再继承自其他类了。而且，包含的头文件中有 <code>#include &quot;runTimeSelectionTables.H&quot;</code> 可以猜想，这个类肯定是作为接口的基类来使用的。<br>经验证，具体的源项类，如 <code>semiImplicitSource</code>，都是继承自 <code>option</code> 类的。当然，这里会用到 RTS 机制来提供灵活地源项选择。和其他的作为接口使用的基类类似， <code>option</code> 类中定义了所有的具体源项类可能用到的控制选项，比如，区域的选择（Points，cellSet，cellZone，mapRegion，all），开始时间（timeStart），持续时间（duration）激活开关（active）以及各个可能调用到的函数。</p>
</li>
</ul>
<p>至此，fvOptions 框架的结构就大体理清了，总结如下图：</p>
<p><img src="/image/fvOptions/fvOptions.png" alt="fvOptions 框架的结构"></p>
<h5 id="参考">参考</h5><ol>
<li><a href="http://www.sourceflux.de/blog/series/fvoptions/" target="_blank" rel="external">http://www.sourceflux.de/blog/series/fvoptions/</a></li>
<li><a href="http://www.openfoam.org/version2.2.0/fvOptions.php" target="_blank" rel="external">http://www.openfoam.org/version2.2.0/fvOptions.php</a></li>
</ol>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://xiaopingqiu.github.io/2016/03/20/fvOptions1/" data-id="cj2lay33g0035kkmbec7eame0" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Code-Explained/">Code Explained</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/fvOptions/">fvOptions</a></li></ul>

    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2016/03/20/fvOptions2/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          fvOptions 之 semiImplicitSource
        
      </div>
    </a>
  
  
    <a href="/2016/03/12/RTS2/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">湍流模型中的 RTS 机制分析</div>
    </a>
  
</nav>

  
</article>


<section id="comments">
  <!-- 多说评论框 start -->
  <div class="ds-thread" data-thread-key="post-fvOptions1" data-title="fvOptions 浅析" data-url="http://xiaopingqiu.github.io/2016/03/20/fvOptions1/"></div>
  <!-- 多说评论框 end -->
  <!-- 多说公共JS代码 start (一个网页只需插入一次) -->
  <script type="text/javascript">
  var duoshuoQuery = {short_name:"xiaopingqiu"};
	(function() {
		var ds = document.createElement('script');
		ds.type = 'text/javascript';ds.async = true;
		ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
		ds.charset = 'UTF-8';
		(document.getElementsByTagName('head')[0] 
		 || document.getElementsByTagName('body')[0]).appendChild(ds);
	})();
	</script>
  <!-- 多说公共JS代码 end -->
</section>

</section>
        
          <aside id="sidebar">
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Categories</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/C/">C++</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/DEM/">DEM</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/OpenFOAM/">OpenFOAM</a><span class="category-list-count">44</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Paraview/">Paraview</a><span class="category-list-count">5</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/swak4Foam/">swak4Foam</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/test/">test</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/vim/">vim</a><span class="category-list-count">1</span></li></ul>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="/tags/Boundary-conditions/">Boundary conditions</a><span class="tag-list-count">6</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/C/">C++</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/CentOS/">CentOS</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Code-Explained/">Code Explained</a><span class="tag-list-count">29</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/LES/">LES</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/LIGGGHTS/">LIGGGHTS</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/ODE/">ODE</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/OpenFOAM/">OpenFOAM</a><span class="tag-list-count">20</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Postprocessing/">Postprocessing</a><span class="tag-list-count">9</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Preprocessing/">Preprocessing</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/RTS/">RTS</a><span class="tag-list-count">3</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/TIL/">TIL</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Windows/">Windows</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/fvOptions/">fvOptions</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/groovyBC/">groovyBC</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/paraview/">paraview</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/test/">test</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/thermophysicalModels/">thermophysicalModels</a><span class="tag-list-count">5</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/turbulence-model/">turbulence model</a><span class="tag-list-count">7</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/vim/">vim</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/wall-functions/">wall functions</a><span class="tag-list-count">4</span></li></ul>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/tags/Boundary-conditions/" style="font-size: 15.56px;">Boundary conditions</a><a href="/tags/C/" style="font-size: 11.11px;">C++</a><a href="/tags/CentOS/" style="font-size: 10px;">CentOS</a><a href="/tags/Code-Explained/" style="font-size: 20px;">Code Explained</a><a href="/tags/LES/" style="font-size: 10px;">LES</a><a href="/tags/LIGGGHTS/" style="font-size: 10px;">LIGGGHTS</a><a href="/tags/ODE/" style="font-size: 10px;">ODE</a><a href="/tags/OpenFOAM/" style="font-size: 18.89px;">OpenFOAM</a><a href="/tags/Postprocessing/" style="font-size: 17.78px;">Postprocessing</a><a href="/tags/Preprocessing/" style="font-size: 11.11px;">Preprocessing</a><a href="/tags/RTS/" style="font-size: 12.22px;">RTS</a><a href="/tags/TIL/" style="font-size: 10px;">TIL</a><a href="/tags/Windows/" style="font-size: 10px;">Windows</a><a href="/tags/fvOptions/" style="font-size: 11.11px;">fvOptions</a><a href="/tags/groovyBC/" style="font-size: 10px;">groovyBC</a><a href="/tags/paraview/" style="font-size: 10px;">paraview</a><a href="/tags/test/" style="font-size: 11.11px;">test</a><a href="/tags/thermophysicalModels/" style="font-size: 14.44px;">thermophysicalModels</a><a href="/tags/turbulence-model/" style="font-size: 16.67px;">turbulence model</a><a href="/tags/vim/" style="font-size: 10px;">vim</a><a href="/tags/wall-functions/" style="font-size: 13.33px;">wall functions</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/05/">五月 2017</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/08/">八月 2016</a><span class="archive-list-count">8</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/06/">六月 2016</a><span class="archive-list-count">5</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/05/">五月 2016</a><span class="archive-list-count">3</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/04/">四月 2016</a><span class="archive-list-count">12</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/03/">三月 2016</a><span class="archive-list-count">6</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/12/">十二月 2015</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/11/">十一月 2015</a><span class="archive-list-count">2</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/10/">十月 2015</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/09/">九月 2015</a><span class="archive-list-count">6</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/08/">八月 2015</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/06/">六月 2015</a><span class="archive-list-count">2</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/05/">五月 2015</a><span class="archive-list-count">6</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/04/">四月 2015</a><span class="archive-list-count">2</span></li></ul>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recents</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2017/05/12/duoshuoAnnouncement/">多说评论系统将停止提供服务</a>
          </li>
        
          <li>
            <a href="/2016/08/27/ParaviewScritps/">Paraview 脚本一例</a>
          </li>
        
          <li>
            <a href="/2016/08/27/ParaviewCamera/">Paraview 中有关 Camera 的操作两例</a>
          </li>
        
          <li>
            <a href="/2016/08/27/ParaviewCustomFilter/">Paraview 中创建 Custom Filter</a>
          </li>
        
          <li>
            <a href="/2016/08/27/ParaviewStreamLineOnSlice/">在 Paraview 中画截面上的流线</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2017 Giskard Q.<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>

<script src="//dn-lbstatics.qbox.me/lbservice/busuanzi/2.0/busuanzi.mini.js"/></script>

    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
    <a href="/atom.xml" class="mobile-nav-link">Rss</a>
  
    <a href="/about" class="mobile-nav-link">About</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css" type="text/css">
  <script src="/fancybox/jquery.fancybox.pack.js" type="text/javascript"></script>


<script src="/js/script.js" type="text/javascript"></script>

<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-62501686-1', 'auto');
  ga('send', 'pageview');

</script>

  </div>
<!-- mathjax config similar to math.stackexchange -->

<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    tex2jax: {
      inlineMath: [ ['$','$'], ["\\(","\\)"] ],
      processEscapes: true
    }
  });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
      tex2jax: {
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
      }
    });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for(i=0; i < all.length; i += 1) {
            all[i].SourceElement().parentNode.className += ' has-jax';
        }
    });
</script>

<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
</body>
</html>